Backdrop

프로그래머스 ▸ 코딩 기초 트레이닝

정수를 나선형으로 배치하기
0

문제 설명

양의 정수 n이 매개변수로 주어집니다. n × n 배열에 1부터 n2 까지 정수를 인덱스 [0][0]부터 시계방향 나선형으로 배치한 이차원 배열을 return 하는 solution 함수를 작성해 주세요.

제한사항

  • 1 ≤ n ≤ 30

입출력 예

nresult
4[[1, 2, 3, 4], [12, 13, 14, 5], [11, 16, 15, 6], [10, 9, 8, 7]]
5[[1, 2, 3, 4, 5], [16, 17, 18, 19, 6], [15, 24, 25, 20, 7], [14, 23, 22, 21, 8], [13, 12, 11, 10, 9]]

입출력 예 설명

입출력 예 #1

  • 예제 1번의 n의 값은 4로 4 × 4 배열에 다음과 같이 1부터 16까지 숫자를 채울 수 있습니다.

    행 \ 열0123
    01234
    11213145
    21116156
    310987

    따라서 [[1, 2, 3, 4], [12, 13, 14, 5], [11, 16, 15, 6], [10, 9, 8, 7]]를 return 합니다.

입출력 예 #2

  • 예제 2번의 n의 값은 5로 5 × 5 배열에 다음과 같이 1부터 25까지 숫자를 채울 수 있습니다.

    행 \ 열01234
    012345
    1161718196
    2152425207
    3142322218
    4131211109

    따라서 [[1, 2, 3, 4, 5], [16, 17, 18, 19, 6], [15, 24, 25, 20, 7], [14, 23, 22, 21, 8], [13, 12, 11, 10, 9]]를 return 합니다.

풀이

이론

2차원 배열을 순회하는 문제예요. 방향을 바꾸면서 순회해야 하기 때문에 direction 변수를 두고, switch 문을 이용해서 각 방향에 따라 다음 좌표를 결정해요.

배열 생성

const answer = [...Array(n)].map(() => []);

Array(n)은 길이가 n인 배열을 생성해요. 이 배열의 각 요소를 map을 이용해서 빈 배열로 채워요.

방향 전환

각 방향 별로 좌표를 다르게 움직여요. 다음 좌표를 갈 수 없거나 이미 숫자가 채워져 있다면 방향을 전환해야 해요.

switch (direction) {
  case 'r':
    if (j + 1 === n || answer[i][j + 1]) {
      direction = 'd';
      i++;
    } else {
      j++;
    }
    break;
  case 'd':
    if (i + 1 === n || answer[i + 1][j]) {
      direction = 'l';
      j--;
    } else {
      i++;
    }
    break;
  case 'l':
    if (j === 0 || answer[i][j - 1]) {
      direction = 'u';
      i--;
    } else {
      j--;
    }
    break;
  case 'u':
    if (i === 0 || answer[i - 1][j]) {
      direction = 'r';
      j++;
    } else {
      i--;
    }
    break;
}

'r' 방향일 때, j + 1 === n이면 다음 좌표가 배열의 범위를 벗어나기 때문에 방향을 'd'로 전환해요. answer[i][j + 1]true인 경우에도 이미 숫자가 채워져 있기 때문에 방향을 'd'로 전환해요. 그렇지 않다면 j를 증가시켜서 다음 좌표(오른쪽)로 이동해요.

마찬가지로 'd', 'l', 'u' 방향일 때도 같은 방식으로 다음 좌표를 결정해요.

코드

function solution(n) {
  const answer = [...Array(n)].map(() => []);
  let [i, j] = [0, 0];
  let direction = 'r';
  for (let k = 1; k <= n ** 2; k++) {
    answer[i][j] = k;
    switch (direction) {
      case 'r':
        if (j + 1 === n || answer[i][j + 1]) {
          direction = 'd';
          i++;
        } else {
          j++;
        }
        break;
      case 'd':
        if (i + 1 === n || answer[i + 1][j]) {
          direction = 'l';
          j--;
        } else {
          i++;
        }
        break;
      case 'l':
        if (j === 0 || answer[i][j - 1]) {
          direction = 'u';
          i--;
        } else {
          j--;
        }
        break;
      case 'u':
        if (i === 0 || answer[i - 1][j]) {
          direction = 'r';
          j++;
        } else {
          i--;
        }
        break;
    }
  }
 
  return answer;
}